<?php
namespace Hilaoyu\LaravelExtend\Supports;
/**
 * Created by laoyu.
 * User: hilaoyu@qq.com
 * Date: 2018/7/12
 * Time: 下午9:33
 */


use Hilaoyu\Utils\UtilArr;
use Hilaoyu\Utils\UtilCli;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Process\PhpExecutableFinder;
use Illuminate\Support\ProcessUtils;

class Cli
{
    static protected $logger = null;
    static protected $log_channel = 'cli';

    static public function setLogChannel(string $log_channel){
        if($log_channel){
            static::$log_channel = trim($log_channel);
            static::logger();
        }

    }


    static public function logger(){

        if(! static::$logger){
            $log_channel = static::$log_channel;

            if(!$log_channel || !(config('logging.channels.'.$log_channel))){
                $log_channel = null;
            }

            static::$logger = Log::channel($log_channel);

        }


        return static::$logger;
    }

    static public function getLoggerOutput(){

        /*$log_channel = static::$log_channel;
        if(!$log_channel || !(config('logging.channels.'.$log_channel))){
            $log_channel = config('logging.default');
        }



        if($log_output = config('logging.channels.'.$log_channel.'.path')){
            return $log_output;
        }*/
        if($logger = static::logger()){
            foreach ($logger->getHandlers() as $handler){
                $url = $handler->getUrl();
                if (substr($url, 0, 1) === '/' || substr($url, 1, 1) === ':' || substr($url, 0, 2) === '\\\\') {
                    return $url;
                }
            }

        }


        return null;
    }

    /**
     * Get the PHP binary.
     *
     * @return string
     */
    static public function phpBinary()
    {
        $phpBinary = ProcessUtils::escapeArgument(
            (new PhpExecutableFinder)->find(false)
        );

        $phpBinary = str_replace("'",'',$phpBinary);
        $phpBinary = str_replace('"','',$phpBinary);
        return $phpBinary;
    }

    /**
     * Get the Artisan binary.
     *
     * @return string
     */
    static public function artisanBinary()
    {
        $artisan_name =  defined('ARTISAN_BINARY')
            ? ProcessUtils::escapeArgument(ARTISAN_BINARY)
            : ProcessUtils::escapeArgument('artisan');

        $artisan_name = str_replace("'",'',$artisan_name);
        $artisan_name = str_replace('"','',$artisan_name);
        return base_path($artisan_name);
    }

    /**
     * 运行 artisan 命令
     * @param $command
     * @param null $output
     * @param string $application_id
     * @param string $application_module_id
     * @param string $env
     * @return mixed
     */
    static public function execute($command,&$output=null,$env='',$logging=true){
        $command = static::buildArtisanCommand($command,$env);



        /*if($application_id ||($application_id = config('appCurrent.application.id'))){
            $command .= ' --applicationId=' . $application_id;
        }
        if($application_module_id || ($application_module_id = config('appCurrent.module.id'))){
            $command .= ' --applicationModuleId=' . $application_module_id;
        }

        if($user_id = Auth::id()){
            $command .= ' --authUserId=' . $user_id;
        }*/

        $output_redirect = null;
        if($logging && is_null($output)){
            $output_redirect = static::getLoggerOutput();
        }
        //dd($command,$output_redirect);
        if ($logging && $logger = static::logger()) {
            $logger->info('execute command: ' .$command);
            UtilCli::registerLogCallback(function ($log,$status)use ($logger){
                if($status){
                    $logger->info(UtilArr::toString($log));
                }else{
                    $logger->error(UtilArr::toString($log));
                }
            });

        }

        $status =  UtilCli::execute($command,$output,$output_redirect);

        if($logging && $output && $logger = static::logger()){
            $logger->info(UtilArr::toString($output,'',false));
        }

        return $status;
    }

    /**
     * @param $command
     * @return string
     */
    static public function buildArtisanCommand($command,$env=''){
        $command = static::phpBinary() . ' ' . static::artisanBinary() . ' ' . $command;
        if($env || ($env = config('app.env',''))){
            $command .= ' --env=' . $env;
        }
        return $command;
    }



}
